/*
 * Copyright (C) Francisco Morero Peyrona. All rights reserved.
 *
 * This software is published under the terms of Open Source 
 * License version 1.1, a copy of which has been included with this
 * distribution in the License.txt file.  
 */
 
package jdbcmanager.swing.desktop;

import java.awt.*;
import javax.swing.*;

/**
 * Provides "virtual desktop" funcitonality: scroll-bars when windows are moved outside 
 * of view port.
 * 
 * @author Francisco Morero Peyrona
 */

final class JxDesktopManager extends DefaultDesktopManager
{
   private JxDesktopPane owner;
   
   /**
    * Constructor
    * 
    * @param owner The owner (creator) of this manager
    */
   public JxDesktopManager( JxDesktopPane owner )
   {
      this.owner = owner;
   }
   
   /**
    * @see javax.swing.DesktopManager#openFrame(javax.swing.JInternalFrame)
    */
   public void openFrame( JInternalFrame f )
   {
      super.openFrame( f );
      resizeDesktop();  
   }

   /**
    * @see javax.swing.DesktopManager#closeFrame(javax.swing.JInternalFrame)
    */
   public void closeFrame( JInternalFrame f )
   {
      super.closeFrame( f );
      resizeDesktop();
   }

   /**
    * @see javax.swing.DesktopManager#maximizeFrame(javax.swing.JInternalFrame)
    */
   public void maximizeFrame( JInternalFrame f )
   {
      super.maximizeFrame( f );
      resizeDesktop();
   }

   /**
    * @see javax.swing.DesktopManager#minimizeFrame(javax.swing.JInternalFrame)
    */
   public void minimizeFrame( JInternalFrame f )
   {
      super.minimizeFrame( f );
      resizeDesktop();
   }

   /**
    * @see javax.swing.DesktopManager#iconifyFrame(javax.swing.JInternalFrame)
    */
   public void iconifyFrame( JInternalFrame f )
   {
      super.iconifyFrame( f );
      resizeDesktop();
   }

   /**
    * @see javax.swing.DesktopManager#deiconifyFrame(javax.swing.JInternalFrame)
    */
   public void deiconifyFrame( JInternalFrame f )
   {
      super.deiconifyFrame( f );
      resizeDesktop();
   }

   /**
    * @see javax.swing.DesktopManager#endDraggingFrame(javax.swing.JComponent)
    */
   public void endDraggingFrame( JComponent f )
   {
      super.endDraggingFrame( f );
      resizeDesktop();
   }

   /**
    * @see javax.swing.DesktopManager#endResizingFrame(javax.swing.JComponent)
    */
   public void endResizingFrame( JComponent f )
   {
      super.endResizingFrame( f );
      resizeDesktop();
   }
   
   //-------------------------------------------------------------------------//
   
   void resizeDesktop()
   {
      JInternalFrame[] aFrame = this.owner.getAllFrames();
      
      int nXmin = 0, nYmin = 0, nXmax = 0, nYmax = 0;
      
      // Finds far-est points
      for( int n = 0; n < aFrame.length; n++ )
      {
         if( aFrame[n].isVisible() )
         {
            nXmin = Math.min( nXmin, aFrame[n].getX() );
            nYmin = Math.min( nYmin, aFrame[n].getY() );
            nXmax = Math.max( nXmax, aFrame[n].getX() + aFrame[n].getWidth()  );
            nYmax = Math.max( nYmax, aFrame[n].getY() + aFrame[n].getHeight() );
         }
      }

      // If bottom-left frame is not beyond JDesktop area, Xmax and Ymax will be the area
      Rectangle rVisible = this.owner.getVisibleRect();
      
      nXmax = Math.max( nXmax, rVisible.width  );
      nYmax = Math.max( nYmax, rVisible.height );

      // Are there frames out of area (up and/or left)?
      if( nXmin < 0 || nYmin < 0 )
      {
         // Re-adjusts all frames to shift negative values to positive (has to shift all frames)
         // because JDestopPane does not allows global coordinates (negative values)
         for( int n = 0; n < aFrame.length; n++ )
             aFrame[n].setLocation( aFrame[n].getX() + Math.abs( nXmin ), aFrame[n].getY() + Math.abs( nYmin ) );

         if( nXmin < 0 )
            nXmax += Math.abs( nXmin );

         if( nYmin < 0 )
            nYmax += Math.abs( nYmin );
      }
      
      this.owner.setPreferredSize( new Dimension( nXmax, nYmax ) );
      this.owner.revalidate();
   
      if( nXmin < 0 || nYmin < 0 )
      {
         Component c = this.owner.getParent();
      
         if( c instanceof JViewport )  
         {                               // 10 -> any number lower that current size
            Rectangle r = new Rectangle( Math.abs( nXmin ), Math.abs( nYmin ), 
                                         this.owner.getWidth(), this.owner.getHeight() ); 
            ((JViewport) c).scrollRectToVisible( r ); 
         }
      }
   }
}